package com.godenwater.recv.server.summit;


import cn.gov.mwr.sl651.utils.ByteUtil;
import com.godenwater.recv.manager.SessionIoFutureListener;
import com.godenwater.recv.model.CommonMessage;
import com.godenwater.recv.server.all.RtuConfig;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.filterchain.IoFilterAdapter;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 报文接收处理器，为加快报文的处理，对接收后的报文仅保存为文件，以提高接收的效率
 *
 * @author 李普军
 * @date 2016-10-18
 */
public class SummitServerDataHandler extends IoFilterAdapter implements IoHandler {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private final SummitServer server;

    private String channel;

    public SummitServerDataHandler(SummitServer server, String channel) {
        this.server = server;
        this.channel = channel;
    }

    /**
     * 消息接收后的处理，只处理业务逻辑，此消息处理是在解码后，所以只需要关注消息体的内容
     */
    public void messageReceived(IoSession session, Object message)
            throws Exception {

        logger.debug("接收通道" + this.channel + " 服务端已收到 " + server.messageSize()
                + " 消息数;");


        if (message instanceof CommonMessage) {
            // 纯粹只处理报文，此消息体已经被解码为单体报文
            CommonMessage msg = (CommonMessage) message;
            SummitMessageHandler.getInstance().perform(channel, session, msg, 0);

        }

    }

    /**
     * {@inheritDoc}
     */
    public void sessionClosed(IoSession session) throws Exception {
        logger.debug("关闭会话  " + session.getRemoteAddress());
        //RtuServer.getInstance().getSessionManager().removeSession(session);
    }

    /**
     * 当session创建连接后，需添加到一个客户端中
     */
    public void sessionCreated(IoSession session) throws Exception {
        logger.debug("----------------------------------------------------------------------");
        logger.debug("创建会话  " + session.getRemoteAddress());
        //RtuServer.getInstance().getSessionManager().createSession(session);
    }

    /**
     * {@inheritDoc} 在此对空闲的session进行关闭
     */
    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {
        try {
            //logger.debug("空闲会话  " + session.getRemoteAddress());
            String stcd = (String) session.getAttribute("STCD");
            String protocol = (String) session.getAttribute("PROTOCOL");
            //山脉协议
            if (StringUtils.equalsIgnoreCase(protocol, "SUMMIT")) {
                System.out.println(">>> 山脉报文下发开始...........");
                //System.out.println(">>> 测站所用通讯号码：telphone = " + telphone);
                System.out.println(">>> 测站配置测站编码：stcd = " + stcd);
                //查找报文
                if (StringUtils.isNotBlank(stcd)) {
                    // 读取下发命令，此片仅每次下发一条报文，等待RTU回复报文后，再次发送下一条报文，以达到顺时下发报文的目的。
                    stcd = StringUtils.leftPad(stcd, 4, "0");
                    File[] downFile = getDownMessage(protocol, stcd);
                    if (downFile.length > 0) {
                        File df = downFile[0];
                        List<String> lines = FileUtils.readLines(df, "UTF-8");
                        //直接下发报文
                        WriteFuture f = null;
                        for (String line : lines) {
                            logger.info(">>line  " + line);
                            //获取功能码
                            String funcode = line.substring(0, 1);
                            if (funcode.equals("1")) {
                                //固态数据提取
                                line = "<09>9," + line.substring(2) + "<cfg>";
                            } else if (funcode.equals("2")) {
                                //实时数据提取
                                line = "<55><cfg>";
                            } else if (funcode.equals("3")) {
                                //校时
                                line = "<01><cfg>";
                                session.write(ByteUtil.HexStringToBinary(ByteUtil.toHexString(line)));
                                SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
                                String tm = sdf.format(new Date());
                                line = "<52>" + tm + "<cfg>";
                            }
                            byte[] rpy_content = ByteUtil.HexStringToBinary(ByteUtil.toHexString(line));
                            logger.debug(">>西安山脉下发报文为：  " + ByteUtil.byteToHexString(rpy_content));
                            f = session.write(rpy_content);
                        }
                        String id = df.getName();
                        f.addListener(new SessionIoFutureListener(protocol, id, stcd));
                    }
                }
                System.out.println(">>> 西安山脉报文下发检测完成");
            }
            session.close(true);// 因为session无测站，保持此会话已无意义
            logger.info("清除山脉会话连接");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 检测是否有下发命令，如果有，则需要将标识切换为等待状态，如果无，则正常状态
     *
     * @return
     */
    public File[] getDownMessage(String protocol, String stcd) {

        String path = RtuConfig.getMsgCmdPath();

//        if (StringUtils.equalsIgnoreCase(protocol, "yy")) {
//            String[] tmpstcd = stcd.split("_");
//            path = path + "/msg/" + protocol + "/" + tmpstcd[0] + "/"
//                    + tmpstcd[1] + "/";
//        } else {
//            path = path + "/msg/" + protocol + "/" + stcd + "/";
//        }
        path = path + "/msg/" + protocol + "/" + stcd + "/";

        File fullPathDir = new File(path);
        if (fullPathDir != null && !fullPathDir.exists()) {
            fullPathDir.mkdirs();
        }

        return fullPathDir.listFiles();

    }

    /**
     * {@inheritDoc}
     */
    public void sessionOpened(IoSession session) throws Exception {
        logger.info("Session Opened...");

    }

    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        logger.debug("会话出现异常  " + session.getRemoteAddress() + " \t"
                + cause.getMessage());
        //RtuServer.getInstance().getSessionManager().removeSession(session);
        session.close(true);

    }

    /**
     * 消息应答事件,表示发送消息成功后，调用这个方法
     */
    public void messageSent(IoSession session, Object message) throws Exception {
        logger.debug("报文下发完成！  ");
        // session.close(true);
    }


    public void inputClosed(IoSession arg0) throws Exception {
        //logger.info("inputClosed 出现异常！151行  " );
    }
}
